﻿package com.zouloux.core.base
{
	import com.zouloux.core.IDisposable;
	import com.zouloux.core.IMovieClip;
	import flash.display.FrameLabel;
	import flash.display.MovieClip;
	import flash.events.Event;
	
	/**
	 * La classe de base pour gérer plus simplement les movieClip
	 * @author ZoulouX
	 */
	public class MovieClipBase extends MovieClip implements IMovieClip, IDisposable
	{
		/**
		 * La largeur du clip
		 */
		protected var _width			:Number			= 0;
		
		/**
		 * La hauteur du clip
		 */
		protected var _height			:Number			= 0;
		
		
		/**
		 * Récupérer une instance de ce displayObject depuis son interface
		 */
		public function get displayObject ():MovieClipBase
		{
			return this;
		}
		
		/**
		 * La largeur du clip
		 */
		override public function get width ():Number { return _width; }
		override public function set width (value:Number):void
		{
			// Actualiser la largeur
			_width = value;
			refresh();
		}
		
		/**
		 * La hauteur du clip
		 */
		override public function get height ():Number { return _height }
		override public function set height (value:Number):void
		{
			// Actualiser la hauteur
			_height = value;
			refresh();
		}
		
		/**
		 * La largeur du clip
		 */
		public function get realWidth ():Number { return super.width; }
		public function set realWidth (value:Number):void
		{
			super.width = value;
		}
		
		/**
		 * La hauteur du clip
		 */
		public function get realHeight ():Number { return super.height }
		public function set realHeight (value:Number):void
		{
			super.height = value;
		}
		
		/**
		 * Le constructeur
		 */
		public function MovieClipBase ()
		{
			// Construire le parent
			super();
			
			// Ecouter l'ajout au stage
			if (stage != null)
				initHandler();
			else
				addEventListener(Event.ADDED_TO_STAGE, initHandler);
		}
		
		/**
		 * Méthode privée appelée lors de l'ajout sur la scène
		 * Cette méthode appèle ensuite son équivalent public
		 * @param	event
		 */
		protected function initHandler (event:Event = null):void
		{
			// Ne plus écouter l'event d'ajout
			removeEventListener(Event.ADDED_TO_STAGE, initHandler);
			
			// Ecouter lorsque le clip est supprimé de la scène
			addEventListener(Event.REMOVED_FROM_STAGE, disposeHandler);
			
			// Appeler la méthode publique associée
			init();
		}
		
		/**
		 * Ajout du clip sur la scène
		 */
		public function init ():void
		{
			
		}
		
		/**
		 * Récupérer le numéro d'une image par le nom de son label
		 * @param	pLabel : Le label de cette image
		 * @param	pStrict : Vérifier si le nom de être strictement vérifié (majuscules et miniscules)
		 * @return
		 */
		final public function getFrameByLabel (pLabel:String, pStrict:Boolean = false):uint
		{
			// Compter le nombre de labels
			var t:uint = currentLabels.length;
			
			// Parcourir tous ces labels
			for (var i:uint = 0; i < t; i++)
			{
				// Récupérer le nom de ce label
				var n:String = FrameLabel(currentLabels[i]).name;
				
				// Vérifier s'il correspond de près ou de loin
				if (pStrict && (n == pLabel) || !pStrict && (n.toLowerCase() == pLabel.toLowerCase()))
					return FrameLabel(currentLabels[i]).frame;
			}
			
			// Sinon on retourne 0
			return 0;
		}
		
		/**
		 * Aller à une image et lire si elle existe
		 * @param	pLabel : Le nom de l'image
		 * @return : Retourne le booleen de la réussite
		 */
		final public function checkAndPlay (pLabel:String):Boolean
		{
			// Récupérer le numéro de la fram
			var n:uint = getFrameByLabel(pLabel);
			
			// Vérifier si l'image à été trouvée
			if (n > 0)
			{
				// On va à l'image
				gotoAndPlay(n);
				
				// Et on retourne que c'est ok
				return true;
			}
			else return false;
		}
		
		/**
		 * Aller à une image est arrêter si elle existe
		 * @param	pLabel : Le nom de l'image
		 * @return : retourne le booleen de la réussite
		 */
		final public function checkAndStop (pLabel:String):Boolean
		{
			// Récupérer le numéro de la fram
			var n:uint = getFrameByLabel(pLabel);
			
			// Vérifier si l'image à été trouvée
			if (n > 0)
			{
				// On va à l'image
				gotoAndStop(n);
				
				// Et on retourne que c'est ok
				return true;
			}
			else return false;
		}
		
		/**
		 * Passer au premier plan
		 */
		final public function bringToFront ():void
		{
			if (parent != null && parent.contains(this))
				parent.setChildIndex(this, parent.numChildren - 1);
		}
		
		/**
		 * Passer en background
		 */
		final public function bringToBack ():void
		{
			if (parent != null && parent.contains(this))
				parent.setChildIndex(this, 0);
		}
		
		/**
		 * Passer au plan au dessus
		 */
		final public function bringUp ():void
		{
			if (parent != null && parent.contains(this))
				parent.setChildIndex(this, Math.min(parent.numChildren - 1, parent.getChildIndex(this) + 1));
		}
		
		/**
		 * Passer au plan en dessous
		 */
		final public function bringDown ():void
		{
			if (parent != null && parent.contains(this))
				parent.setChildIndex(this, Math.max(0, parent.getChildIndex(this) - 1));
		}
		
		/**
		 * Actualiser le composant graphique
		 */
		protected function refresh ():void
		{
			
		}
		
		/**
		 * Méthode privée appelée lors de la suppression de la scène
		 * Cette méthode appèle ensuite son équivalent public
		 * @param	event
		 */
		protected function disposeHandler (event:Event = null):void
		{
			// Supprimer l'event d'écoute de suppression
			removeEventListener(Event.REMOVED_FROM_STAGE, disposeHandler);
			
			// Appel de son équivalent public
			dispose();
		}
		
		/**
		 * Méthode appelée lorsque le clip est supprimé de la scène
		 */
		public function dispose ():void
		{
			
		}
	}
}